简要题意:
初始有
元钱,然后每次可以花费 ( )元,有 的概率获得 元, 的概率不获得钱。问获得 ( )元的概率。对 取模。
首先若
现在来解决
我们可以把
考虑从后往前 dp。 我们记
但是这只能解决
但是循环小数好啊。考虑求循环节的过程(竖式模拟除法),发现,若当前被除数是
那么,设这个循环节起始位置是
这就是一个线性方程。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int P = 998244353, Q = 616898040;
int a, z, q, i, j;
int vis[2000008];
bitset<2000008> tp;
int Qpow(int x, int y)
{
int ret = 1;
for (; y; y >>= 1) {
if (y & 1) ret = ret * x % P;
x = x * x % P;
}
return ret;
}
signed main()
{
cin >> a >> z >> q;
for (i = 1; !vis[a]; i++) {
vis[a] = i;
a = a + a;
if (a >= z) a -= z, tp.set(i);
}
int k = 1, b = 0, p = q * Q % P; q = 1 + P - p;
for (j = vis[a], i--; i >= j; i--) {
if (tp[i]) k = k * q % P, b = (b * q + p) % P;
else k = k * p % P, b = b * p % P;
}
k = (P - b) * Qpow(k - 1, P - 2) % P;
while (--j) {
if (tp[j]) k = (p + q * k) % P;
else k = p * k % P;
}
cout << k << '\n';
return 0;
}